package com.wxmit.framework.web.handler;

import com.wxmit.base.domain.ApiResult;
import com.wxmit.framework.web.annotation.NoResponseBody;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.lang.reflect.Method;
import java.util.Objects;

/**
 * @Description 统一封装处理restful接口返回值
 * @Author huangxiong
 * @Date 2022/7/11 15:04
 * @Version V1.0
 */
@RestControllerAdvice
@Slf4j
public class ApiResponseBodyAdvice  implements ResponseBodyAdvice<Object> {


    @Value("${ss.info.base-package}")
    private String basePackage;

    @Override
    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> converterType) {
        // 避免空指针
        Method method = methodParameter.getMethod();
        if(Objects.isNull(method))return false;

        String clazzPath = methodParameter.getExecutable().getDeclaringClass().getName();
        /**
         *  判断是否需要处理
         *  1. 需要是自己编写的类 （basePackage 开头的）
         * // 2. 返回值 不为 void
         *  3. 返回值 不为 ApiResult
         *  4. 没有 @NoResponseBody 注解
         */
        return  isStartsWith(clazzPath) &&
//                !method.getReturnType().isAssignableFrom(Void.TYPE)    &&
                !methodParameter.getParameterType().equals(ApiResult.class)  &&
                !methodParameter.hasMethodAnnotation(NoResponseBody.class);
    }

    /**
     *  判断类路径 是否满足要求
     * @return
     */
    public Boolean isStartsWith(String clazzPath){

        return clazzPath.startsWith(basePackage) ;
    }

    @Override
    public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType
            , Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        return ApiResult.successWithData(o);
    }
}
